﻿using System;
using System.IO;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using System.ServiceProcess;

using DreamCube.WebServer.WinService;
using DreamCube.WebServer.WinServiceModel;
using DreamCube.WinForm.Common;
using DreamCube.Foundation.Basic.Utility;
using DreamCube.Foundation.Basic.Objects;
using DreamCube.Foundation.Serialization;
using DreamCube.Framework.Utilities.BasicObject;

namespace WebServer.WinServiceManager
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        //主服务
        private Service mainService = null;
        /// <summary>
        /// 窗体显示完之后，先检测对应的windows服务器是否存在
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Shown(Object sender, EventArgs e)
        {
            lb_serverState.Text = "正在检查...";
            ThreadPool.QueueUserWorkItem(new WaitCallback((oIn) =>
            {
                //采用windows服务
                //mainService = new WinAppService();
                //CheckServiceState();
                ConfigForm();
                StartCheckServiceState();
            }), null);
        }

        /// <summary>
        /// 定时器
        /// </summary>
        private System.Threading.Timer timer = null;
        /// <summary>
        /// 开始检查服务的状态
        /// </summary>
        private void StartCheckServiceState()
        {
            if (!ValidateData()) return;
            if (timer == null)
            {
                timer = new System.Threading.Timer(new TimerCallback((o) =>
                {
                    try
                    {
                        DoCheckServiceState();
                    }
                    catch (Exception)
                    { }
                    finally
                    {
                        timer.Change(5000, Timeout.Infinite);
                    }
                }), null, 0, Timeout.Infinite);
            }
        }

        /// <summary>
        /// 检查服务的状态
        /// </summary>
        private void DoCheckServiceState()
        {
            Boolean isRunning = false;
            try
            {
                String result = MyWeb.PostTo(Common.WebLivePagePath, "");
                isRunning = result == "true";
            }
            catch (Exception)
            {
                isRunning = false;
            }
            MyControl.ControlInvoke(this, new Action(() =>
            {
                if (isRunning) //服务器崩溃了
                {
                    lb_serverState.Text = "运行ing！";
                }
                else
                {
                    lb_serverState.Text = "服务器已停止！";
                    StartApp();
                }
            }));
        }

        private void StartApp()
        {
            try
            {
                //MyLog.MakeLog("守护进程重启了服务器！！！！！！！！", MyLog.LogType.Debug, MyLog.LogTarget.SystemLog);
                MyControl.ControlInvoke(this, new Action(() =>
                {
                    lb_serverState.Text = "正在启动服务器...";
                }));
                DreamCube.Foundation.Basic.Utility.MyProcess.KillProcessByName(Common.IISProcessName);
                MyCMD.RunEXE(Common.IISAppPath, "true", 10 * 1000, false);
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
            }
        }

        /// <summary>
        /// 配置窗体数据
        /// </summary>
        private void ConfigForm()
        {
            ObjectX obj = ObjectXHelper.CreateObjFromJSONRegistry_LocalMachine(Common.ConfigDataRegistryKey, Common.ConfigDataPropertyName_KeepLive);
            MyControl.ControlInvoke(this, new Action(() =>
            {
                ObjectXHelperEx.WriteObjToForm(obj, this);
            }));
        }

        /// <summary>
        /// 检查服务的状态
        /// </summary>
        private void CheckServiceState()
        {
            //主服务进程
            if (mainService.Status != MyWinService.ServiceStatus.NotExist)
            {
                MyControl.ControlInvoke(this, new Action(() =>
                {
                    try
                    {
                        lb_serverState.Text = MyType.GetFieldDescription(typeof(MyWinService.ServiceStatus), mainService.Status.ToString());
                    }
                    catch (Exception ex)
                    {
                        MyLog.MakeLog(ex);
                    }

                    //启动服务按钮
                    btn_setup.Enabled = true;
                    //卸载标志
                    btn_setup.Tag = "u";
                    btn_setup.Text = "点击卸载服务";

                    btn_StartServer.Enabled = true;
                    //启用启动服务的按钮
                    if (mainService.Status != MyWinService.ServiceStatus.Running)
                    {
                        //启动服务
                        btn_StartServer.Tag = "start";
                        btn_StartServer.Text = "启动服务器";
                    }
                    else
                    {
                        btn_StartServer.Text = "停止服务器";
                        btn_StartServer.Tag = "stop";
                    }
                }));
            }
            else
            {
                MyControl.ControlInvoke(this, new Action(() =>
                {
                    lb_serverState.Text = "服务未安装，请先安装服务！";
                    //启动服务按钮
                    btn_setup.Enabled = true;
                    //安装标志
                    btn_setup.Tag = "s";
                    btn_setup.Text = "点击安装服务";
                    //禁止启动服务的按钮
                    btn_StartServer.Enabled = false;
                }));
            }
        }

        /// <summary>
        /// 安装/卸载按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_setup_Click(Object sender, EventArgs e)
        {
            String operaterText = "";
            try
            {
                Button btn = sender as Button;
                if (btn != null)
                {
                    if (MyObject.ToStringEx(btn.Tag) == "s") //执行安装服务的操作
                    {
                        operaterText = "安装";
                        //执行卸载操作
                        ThreadPool.QueueUserWorkItem(new WaitCallback((oIn) =>
                        {
                            try
                            {
                                DoSetupService();
                                //在安装器里面写这一段代码即可。
                                //MyWaitingForm.Show(this, "正在启动的服务", "提醒", false, null);
                                //DoStartService();
                                //mainService.Start();
                                CheckServiceState();
                            }
                            catch (Exception ex)
                            {
                                MyLog.MakeLog(ex);
                            }
                            finally
                            {
                                MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                                {
                                    MyWaitingForm.WaitingForm.Hide();
                                }));
                            }
                        }), null);
                    }
                    else if (MyObject.ToStringEx(btn.Tag) == "u") //执行卸载服务的操作
                    {
                        operaterText = "卸载";
                        //执行卸载操作
                        ThreadPool.QueueUserWorkItem(new WaitCallback((oIn) =>
                        {
                            try
                            {
                                mainService.UnInstall();
                                CheckServiceState();
                            }
                            catch (Exception ex)
                            {
                                MyLog.MakeLog(ex);
                            }
                            finally
                            {
                                MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                                {
                                    MyWaitingForm.WaitingForm.Hide();
                                }));
                            }
                        }), null);
                    }
                    String msg = String.Format("正在执行{0}", operaterText);
                    MyWaitingForm.Show(this, msg, "提醒", false, null);
                }
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
                MessageBoxEx.Show(String.Format("{0}失败！", operaterText), "提醒");
            }
            finally
            {
                MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                {
                    MyWaitingForm.WaitingForm.Hide();
                }));
            }
        }

        /// <summary>
        /// 执行安装服务
        /// </summary>
        private void DoSetupService()
        {
            try
            {
                mainService.Setup();
                //同时写入配置文件数据
                //DoSaveConfig();
                MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                {
                    MessageBoxEx.Show(MyWaitingForm.WaitingForm, "安装服务成功！", "提醒");
                }));
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
                MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                {
                    MessageBoxEx.Show(MyWaitingForm.WaitingForm, "安装服务失败！", "提醒");
                }));
            }
        }

        /// <summary>
        /// 保存配置按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_saveConfig_Click(object sender, EventArgs e)
        {
            try
            {
                if (ValidateData())
                {
                    DoSaveConfig();
                    StartCheckServiceState();
                }
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
                MessageBoxEx.Show("保存配置失败！", "提醒");
            }
        }

        /// <summary>
        /// 执行保存配置的方法
        /// </summary>
        private void DoSaveConfig()
        {
            //ObjectX obj = ObjectXHelperEx.CreateObjFromForm(this);
            if (ValidateData())
            {
                KeepLiveServerConfig config = new KeepLiveServerConfig
                {
                    IISAppPath = txt_iisAppPath.Text,
                    AutoRun = ck_autoRun.Checked
                };
                //把配置数据保存到注册表中
                config.SaveJSONToRegistry_LocalMachine(Common.ConfigDataRegistryKey, Common.ConfigDataPropertyName_KeepLive);
                MessageBoxEx.Show("保存成功！", "提醒");
            }
        }

        /// <summary>
        /// 启动服务
        /// </summary>
        private void DoStartService()
        {
            try
            {
                mainService.Start();
            }
            catch (System.ServiceProcess.TimeoutException ex)
            {
                MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() => {
                    MessageBoxEx.Show(MyWaitingForm.WaitingForm, "启动服务超时，详情请查看日志！", "提醒");
                }));
                MyLog.MakeLog(ex);
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
            }
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        private void DoStopService()
        {
            try
            {
                mainService.Stop();
            }
            catch (System.ServiceProcess.TimeoutException ex)
            {
                MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                {
                    MessageBoxEx.Show(MyWaitingForm.WaitingForm, "停止服务超时，详情请查看日志！", "提醒");
                }));
                MyLog.MakeLog(ex);
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
            }
        }

        /// <summary>
        /// 验证数据是否合法的
        /// </summary>
        /// <returns></returns>
        protected Boolean ValidateData()
        {
            //Int32 port = 80;
            //if (!(Int32.TryParse(txt_port.Text, out port) && port >= 1 && port <= 60000))
            //{
            //    MessageBoxEx.Show("端口号必须为1-60000！", "提醒");
            //    return false;
            //}
            //if (String.IsNullOrEmpty(txt_PhysicalPath.Text) || !Directory.Exists(txt_PhysicalPath.Text))
            //{
            //    MessageBoxEx.Show("指定的网站目录不存在！", "提醒");
            //    return false;
            //}
            //if (String.IsNullOrEmpty(txt_MainServerUrl.Text))
            //{
            //    MessageBoxEx.Show("主网站的Url不能为空！", "提醒");
            //    return false;
            //}
            //if (String.IsNullOrEmpty(txt_hostDllFilePath.Text) || !File.Exists(txt_hostDllFilePath.Text))
            //{
            //    MessageBoxEx.Show("指定的承载Dll文件不存在！", "提醒");
            //    return false;
            //}
            if (String.IsNullOrEmpty(txt_iisAppPath.Text) || !File.Exists(txt_iisAppPath.Text))
            {
                MessageBoxEx.Show("指定的IIS程序文件不存在！", "提醒");
                return false;
            }
            return true;
        }

        /// <summary>
        /// 启动服务按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_StartServer_Click(object sender, EventArgs e)
        {
            try
            {
                String operatorText = "启动";
                if (btn_StartServer.Tag.ToString() == "stop")
                {
                    operatorText = "停止";
                    (new Action(() =>
                    {
                        try
                        {
                            //DoStopService();
                            mainService.Stop();
                            CheckServiceState();
                        }
                        finally
                        {
                            MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                            {
                                MyWaitingForm.WaitingForm.Hide();
                            }));
                        }
                    })).BeginInvoke(null, null);
                }
                else
                {
                    operatorText = "启动";
                    (new Action(() =>
                    {
                        try
                        {
                            //DoStartService();
                            if (ValidateData())
                            {
                                mainService.Start();
                                CheckServiceState();
                            }
                        }
                        finally
                        {
                            MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                            {
                                MyWaitingForm.WaitingForm.Hide();
                            }));
                        }
                    })).BeginInvoke(null, null);
                }
                MyWaitingForm.Show(this, String.Format("正在{0}服务", operatorText), "提醒", false, null);
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
            }
            finally
            {
                MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                {
                    MyWaitingForm.WaitingForm.Hide();
                }));
            }
        }

        /// <summary>
        /// 关闭守护进程的按钮单击事件（此方法已作废）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void linkLabel1_LinkClicked(Object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (MessageBoxEx.Show(this, "停止守护进程之后，如果主服务崩溃了，将会导致无法重新启动，确定要关闭么？", "确认提醒", MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK)
            {
                (new Action(() =>
                {
                    try
                    {
                        MyWinService.StopService(Common.KeepLiveServiceName, new TimeSpan(0, 0, 20));
                        CheckServiceState();
                    }
                    catch (Exception ex)
                    {
                        MyLog.MakeLog(ex);
                    }
                    finally
                    {
                        MyControl.ControlInvoke(MyWaitingForm.WaitingForm, new Action(() =>
                        {
                            MyWaitingForm.WaitingForm.Hide();
                        }));
                    }
                })).BeginInvoke(null, null);
                MyWaitingForm.Show(this, String.Format("正在{0}服务", "停止守护进程"), "提醒", false, null);
            }
        }

        private void lb_serverState_Click(object sender, EventArgs e)
        {

        }

        private void label6_Click(object sender, EventArgs e)
        {

        }

        private void label10_Click(object sender, EventArgs e)
        {

        }

        private void txt_iisAppPath_TextChanged(object sender, EventArgs e)
        {

        }

        private void ck_autoRun_CheckedChanged(object sender, EventArgs e)
        {
            MyRegistry.Example.ConfigAutoStartApp("South PrintServerManager", ck_autoRun.Checked);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            this.Hide();
        }

        private void 退出程序ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBoxEx.Show(this, "你确定要退出打印服务器吗？", "确认", MessageBoxButtons.OKCancel,
                 MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
            {
                //停止服务器
                notifyIcon1.Visible = false;
                this.Close();
                this.Dispose();
                Application.Exit();
            }       
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            //双击显示
            if (e.Button == MouseButtons.Left)
            {
                this.Show();
                this.WindowState = FormWindowState.Normal;
                this.Activate();
            }
        }
    }
}
